trigger OOTO_Initiate_AccountShares on OOTO_Agent__c (before update) {
	// Loop though triggered OOTO records
	    
	for (OOTO_Agent__c a : Trigger.new){
	    
	    //First we should insure the Start and Stop dates are valid
	    //Check that status is Submitted
	    if (a.Status__c == 'New' || a.Status__c == 'Submitted'){
    		if (a.Start_date__c < System.today()){
    			a.Start_date__c.addError('Start date can not be prior to ' + System.now().format('MM-dd-yyyy'));
    		}
    		else if (a.Stop_date__c < System.today()){
    			a.Stop_date__c.addError('Stop date can not be prior to ' + System.now().format('MM-dd-yyyy'));
    		}
    		else if (a.Stop_date__c < a.Start_date__c) {
    			a.Stop_date__c.addError('Stop date cannot come before ' + a.Start_date__c);
    		}
       	}	
		
		//Status NEW
		
		//Check that status is approved
       	if (a.Status__c == 'Approved'){
    		//Check for valid dates again since they could have been changed.
    		// We only need to check Stop date since the approval could have been delayed  
    		if (a.Stop_date__c < System.today()){
    			a.Stop_date__c.addError('Stop date can not be prior to ' + System.now().format('MM-dd-yyyy'));
    		}
    		else if (a.Stop_date__c < a.Start_date__c) {
    			a.Stop_date__c.addError('Stop date cannot come before ' + a.Start_date__c);
    		}
    		
    		Database.SaveResult[] asr = new Database.SaveResult[]{};
    		AccountShare[] acc_share = new AccountShare[]{};
    		OOTO_AccountShare__c[] agnt_share = new OOTO_AccountShare__c[]{};

    		//Get list of all Accounts for the Owner (using batch mode loop)
	   		//This returns batches of 200 Rows
	   		for (Account[] acc_list : [SELECT Id, OwnerId FROM Account WHERE OwnerID = :a.OwnerID]) {
    			acc_share.clear();
    			// Here we step through each subset to build Account Share Map for bulk inserts
    			for (Account acc : acc_list){
    				//Add values to record
    				acc_share.add(new AccountShare(
    				AccountId = acc.Id,
    				UserOrGroupId = a.Substitute__c,
    				OpportunityAccessLevel = a.Opportunity_Access__c,
    				CaseAccessLevel = a.Case_Access__c,
    				AccountAccessLevel = a.Account_Access__c));
    			}
    			// Perform batch inserts
    			try {
    				// Insert AccountShares
    				asr = Database.Insert(acc_share, true);
    				
    				//Associate AccountSharing records with OOTO_Agent so they can be removed at Stop date or upon delete.
    				agnt_share.clear();
    				for (Database.SaveResult sr : asr) {
    					agnt_share.add(new OOTO_AccountShare__c(
    						AccountShare__c = sr.getID(),
    						Absense_record__c = a.Id
    					));
    				}
    				asr = Database.Insert(agnt_share, true);
    			}
    			catch (Exception e){
    				System.debug('Error inserting AccountShares\n' +e);
    				a.addError('Error: Could not share accounts. Please contact your system administrator');
    			}
    		}
      		//Set status to Active so we don't do this again
      		a.Status__c='Active';
		}
		
		// Check that status is Disabled
       	if (a.Status__c == 'Disabled'){
    		
    		//Get list of OOTO_SharedAccounts records for this Agent
    		Database.DeleteResult[] dsr = new Database.DeleteResult[]{};
    		for (OOTO_AccountShare__c[] agnt_share_del : [SELECT AccountShare__c FROM OOTO_AccountShare__c WHERE Absense_record__c = :a.Id]) {
    			AccountShare[] acc_share_del = new AccountShare[]{};
    			OOTO_AccountShare__c[] agnt_del = new OOTO_AccountShare__c[]{};
    			
    			for (OOTO_AccountShare__c share_rec_del : agnt_share_del){
    				//Assemble delete array
    				acc_share_del.add(new AccountShare(id = share_rec_del.AccountShare__c));
    			}
    			try {
    				//Delete AccountShares
    				dsr = Database.Delete(acc_share_del);
    				// Build array for deleting OOTO_AccountShare__c records.
    				//for (Database.DeleteResult dr : dsr) {
    				//	agnt_del.add(new OOTO_AccountShare__c(id = dr.getID()));
    				//}
    				//Delete records in OOTO_AccountShare__c
    				dsr = Database.Delete(agnt_share_del);
    			}
    			catch (Exception e){
    				System.debug('Error removing AccountShares\n' +e);
    				a.addError('Error: Could not remove share accounts. Please contact your system administrator');
    			}
    		}
    		    		
    		//Set status to Closed so we don't do this again
    		a.Status__c='Closed';
		}		
	}
}